<!--  -->
<template>
  <div class="test4">
    <span class="title">测试四</span>
    <div class="formBox">
      <el-button type="primary" @click="showDialog">创建表单</el-button>
    </div>
    <!-- 创建组件弹窗 -->
    <el-dialog title="添加组件" :visible.sync="isShowAdd" width="35%" @close="closeDialog">
      <el-form class="typeForm" :model="typeData" ref="typeData" label-width="140px">
        <!-- 是否关联组件 -->
        <el-form-item
          v-model="typeData.isChild"
          class="radio_groups"
          v-if="isEdit && isEditData.type === 'radio'"
          label="是否关联为子组件"
        >
          <el-radio v-model="typeData.isChild" :label="true">是</el-radio>
          <el-radio v-model="typeData.isChild" :label="false">否</el-radio>
        </el-form-item>

        <el-form-item v-if="isEdit && isEditData.type === 'radio' && typeData.isChild" label="关联选项">
          <el-checkbox-group v-model="typeData.ChildGroup">
            <el-checkbox v-for="(item,key) in isEditData.groups" :key="key" :label="item.label"></el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <el-form-item label="标题">
          <el-input v-model="typeData.label" placeholder="请输入标题"></el-input>
        </el-form-item>

        <el-form-item label="类型">
          <el-select v-model="typeData.type" placeholder="请选择类型">
            <el-option v-for="(item, key) in typeGroups" :key="key" v-bind="{...item}"></el-option>
          </el-select>
        </el-form-item>

        <!-- 填写选项信息 -->
        <el-form-item
          v-model="typeData.selectGroups"
          class="option_box"
          v-if="typeData.type === 'select' || 
					typeData.type === 'checkbox' ||  
					typeData.type === 'radio'"
          label="选项"
        >
          <div class="option_group">
            <div class="option_content" v-for="(item, index) in typeData.selectGroups" :key="index">
              <el-form-item class="option">
                <el-input v-model="item.label" :placeholder="'选项' + (index+1)"></el-input>
              </el-form-item>
              <span class="icon_box" v-if="typeData.selectGroups.length > 1">
                <i @click="delOption(index)" class="el-icon-remove"></i>
              </span>
              <span class="icon_box" v-if="index === typeData.selectGroups.length - 1">
                <i @click="addOption" class="el-icon-circle-plus"></i>
              </span>
            </div>
          </div>
        </el-form-item>

        <!-- 填写规则 -->
        <el-form-item
          v-if="typeData.type === 'input' ||
          typeData.type === 'textarea'"
          class="rules_box"
          label="填写规则"
          v-model="typeData.rules"
        >
          <div class="rules_group">
            <div class="rules_content" v-for="(item, index) in typeData.rules" :key="index">
              <div class="rules">
                <el-select v-model="item.rule" placeholder="请选择规则（选填）">
                  <el-option
                    v-for="val in rulesGroups"
                    :disabled="val.isDisabled"
                    :key="val.value"
                    :label="val.label"
                    :value="val.value"
                  ></el-option>
                </el-select>
                <el-input
                  class="rules_input"
                  v-if="item.rule === 'max' ||
            item.rule === 'min'"
                  v-model="item.value"
                  placeholder="请输入长度"
                ></el-input>

                <el-input
                  v-if="item.rule !== null"
                  class="rules_input"
                  v-model="item.message"
                  placeholder="请输入错误提示语"
                ></el-input>
              </div>
              <span class="icon_box" v-if="typeData.rules.length > 1">
                <i @click="delRules(index)" class="el-icon-remove"></i>
              </span>
              <span class="icon_box" v-if="index === typeData.rules.length - 1">
                <i @click="addRules" class="el-icon-circle-plus"></i>
              </span>
            </div>
          </div>
        </el-form-item>

        <!-- 提示语 -->
        <el-form-item
          v-if="typeData.type !== 'data_upload' &&
        typeData.type !== 'image_upload'"
          v-model="typeData.placeholder"
          label="提示语"
        >
          <el-input v-model="typeData.placeholder" placeholder="请输入提示语（选填）"></el-input>
        </el-form-item>

        <!-- 文件、图片上传相关 -->
        <!-- 上传数量限制 -->
        <el-form-item
          label="数量限制"
          v-if="typeData.type === 'data_upload' ||
        typeData.type === 'image_upload'"
        >
          <el-input v-model="typeData.limit" placeholder="请输入数量（选填）"></el-input>
        </el-form-item>

        <!-- 填写描述信息 -->
        <el-form-item
          v-model="typeData.message"
          label="描述"
          v-if="typeData.type === 'data_upload' ||
				typeData.type === 'image_upload'"
        >
          <el-input v-model="typeData.message" placeholder="请输入描述（选填）"></el-input>
        </el-form-item>

        <!-- 文片、图片上传类型限制 -->
        <el-form-item
          label="上传类型限制"
          v-if="typeData.type === 'data_upload' ||
        typeData.type === 'image_upload'"
        >
          <el-checkbox-group v-model="typeData.upload_type" v-if="typeData.type === 'data_upload'">
            <el-checkbox v-for="(item,index) in upload_flie_groups" :key="index" :label="item"></el-checkbox>
          </el-checkbox-group>

          <el-checkbox-group v-model="typeData.upload_type" v-if="typeData.type === 'image_upload'">
            <el-checkbox v-for="(item,index) in upload_img_groups" :key="index" :label="item"></el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <!-- 必填按钮 -->
        <el-form-item label="是否必填" class="radio_groups">
          <el-radio v-model="typeData.required" :label="true">是</el-radio>
          <el-radio v-model="typeData.required" :label="false">否</el-radio>
        </el-form-item>

        <!-- 按钮 -->
        <el-form-item class="button_group">
          <el-button type="primary" @click="submit('typeData')">立即创建</el-button>
          <el-button @click="resetForm('typeData')">重置</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <Drag ref="drag" :formData="formData" @submit="onSumbit" @formDrag="formDrag">
      <template slot="form-icon" slot-scope="scope">
        <div class="form_template">
          <span class="icon_box" v-if="isShowEditIcon">
            <i @click="showDialog(scope.data)" class="el-icon-circle-plus"></i>
          </span>
          <span class="icon_box" v-if="isShowEditIcon">
            <i @click="delComponent(scope.data)" class="el-icon-remove"></i>
          </span>
        </div>
      </template>
      <template v-slot:button>
        <el-button @click="editForm">编辑表单</el-button>
        <el-button @click="saveForm">保存编辑</el-button>
      </template>
    </Drag>
  </div>
</template>

<script>
export default {
  data() {
    return {
      id: 1,
      isShowAdd: false, //弹窗显示控制
      isShowEditIcon: false,
      isEdit: false,
      isEditData: null,
      typeData: {
        //新建组件数据
        type: "", //组件类型
        label: "", //组件标题
        required: true, //是否必填
        placeholder: "", //默认提示
        message: "", //上传组件提示语
        limit: "", //上传文件数量限制
        ChildGroup: [],
        parent_id: "",
        isChild: false,
        upload_type: [], //上传文件类型
        rules: [
          //规则
          {
            rule: "",
            value: "",
            message: ""
          }
        ],
        selectGroups: [
          //多选组件选项
          {
            label: "",
            value: ""
          }
        ]
      },
      typeGroups: [
        //可选组件类型
        {
          label: "输入框",
          value: "input"
        },
        {
          label: "选择框",
          value: "select"
        },
        {
          label: "日期选择",
          value: "date_picker"
        },
        {
          label: "时间选择",
          value: "time_picker"
        },
        // {
        //   label: "按钮",
        //   value: "switch"
        // },
        {
          label: "多选框",
          value: "checkbox"
        },
        {
          label: "单选框",
          value: "radio"
        },
        {
          label: "文本域",
          value: "textarea"
        },
        {
          label: "文件上传",
          value: "data_upload"
        },
        {
          label: "图片上传",
          value: "image_upload"
        }
      ],
      rulesGroups: [
        //可选规则
        {
          label: "无",
          value: null,
          only: false //唯一规则，当该值被选中，则其他规则中 only === true 的规则被禁用
        },
        {
          label: "最小长度",
          value: "min",
          isDisabled: false,
          only: false
        },
        {
          label: "最大长度",
          value: "max",
          isDisabled: false,
          only: false
        },
        // {
        //   label: "只能输入字母",
        //   value: "alpha",
        //   isDisabled: false,
        //   only: true
        // },
        {
          label: "只能输入数字",
          value: "numeric",
          isDisabled: false,
          only: true
        },
        // {
        //   label: "只能输入数字或字母",
        //   value: "alpha_num",
        //   isDisabled: false,
        //   only: true
        // },
        {
          label: "只能输入邮箱 (例:123456789@qq.com)",
          value: "email",
          isDisabled: false,
          only: true
        },
        {
          label: "只能输入有效链接 (例:http://www.baidu.com)",
          value: "url",
          isDisabled: false,
          only: true
        }
      ],
      upload_flie_groups: [".txt", ".doc", ".xls", ".wps", ".ppt", ".pdf"], //上传文件类型
      upload_img_groups: [".jpg", ".png", ".bmp", ".gif", ".svg"], //上传图片类型
      formData: []
    };
  },
  created() {},
  computed: {},
  methods: {
    showDialog(data) {
      this.isShowAdd = true;
      if ("name" in data) {
        console.log(data);
        this.isEdit = true;
        this.isEditData = data;
      }
    },
    closeDialog() {
      this.isShowAdd = false;
      this.isEdit = false;
      this.isEditData = null;
    },
    // 重置表单
    resetForm(formName) {
      this[formName] = {
        //新建组件数据
        type: "", //组件类型
        label: "", //组件标题
        required: true, //是否必填
        placeholder: "", //默认提示
        message: "", //上传组件提示语
        limit: "", //上传文件数量限制
        ChildGroup: [],
        parent_id: "",
        isChild: false,
        upload_type: [], //上传文件类型
        rules: [
          //规则
          {
            rule: "",
            value: "",
            message: ""
          }
        ],
        selectGroups: [
          //多选组件选项
          {
            label: "",
            value: ""
          }
        ]
      };
      this.$nextTick(() => {
        this.$refs[formName].resetFields();
      });
    },
    // 创建自定义表单
    submit(formName) {
      let d = this.typeData, //创建表单数据
        t = d.type, //创建类型
        sg = this.typeData.selectGroups, //表单选项
        r = d.rules, //表单规则
        f = this.formData, //表单数据
        ef = this.isEditData, //编辑中组件数据
        newRules = [],
        laravel_rule = "";

      this.$refs[formName].validate(valid => {
        if (valid) {
          // 输入验证
          // 验证标题
          if (!this.typeData.label) {
            this.$alert("标题不能为空");
            return false;
          }
          // 验证类型
          if (!t) {
            this.$alert("类型不能为空");
            return false;
          }
          // 验证选择框、单选框、多选框
          if (t === "select" || t === "checkbox" || t === "radio") {
            if (sg.length < 2) {
              this.$alert("选项不能少于两个");
              return false;
            } else {
              for (var idx in sg) {
                if (t === "select") {
                  sg[idx].value = sg[idx].label;
                } else if (t === "checkbox") {
                  delete sg[idx].value;
                } else if (t === "radio") {
                  delete sg[idx].value;
                }
                if (!sg[idx].label) {
                  this.$alert("选项不能为空");
                  return false;
                }
              }
            }
          }
          // 添加规则
          // 必填
          if (d.required) {
            newRules.push({
              required: true,
              message: `${d.label}不能为空`,
              trigger: "blur"
            });
            laravel_rule += "required|";
          }
          // 输入框、文本域规则
          if (t === "input" || t === "textarea") {
            for (var i in r) {
              let obj = {};
              let rule = r[i].rule;
              if (rule === "max" || rule === "min") {
                obj[rule] = Number(r[i].value);
                laravel_rule += `${rule}:${Number(r[i].value)}|`;
                if (rule === "max") {
                  obj.message =
                    r[i].message || `输入长度错误,最大长度为${r[i].value}`;
                } else {
                  obj.message =
                    r[i].message || `输入长度错误,最小长度为${r[i].value}`;
                }
                obj.trigger = "blur";
                newRules.push(obj);
              } else {
                laravel_rule += `${rule}|`;
                switch (rule) {
                  case "numeric":
                    newRules.push({
                      type: "number",
                      message: r[i].message || "格式错误,只能输入数字",
                      trigger: "blur"
                    });
                    break;
                  case "email":
                    newRules.push({
                      type: "email",
                      message: r[i].message || "格式错误,只能输入邮箱",
                      trigger: "blur"
                    });
                    break;
                  case "url":
                    newRules.push({
                      type: "url",
                      message: r[i].message || "格式错误,只能输入链接",
                      trigger: "blur"
                    });
                    break;
                }
              }
            }
          }

          // 上传组件规则
          let config = {};
          if (t === "data_upload" || t === "image_upload") {
            config.limit = Number(d.limit);
            config.multiple = true;
            config.accept = d.upload_type.join(",");
          }

          laravel_rule = laravel_rule.substr(0, laravel_rule.length - 1);

          // 生成组件数据
          let formData = {
            name: `${d.label}-${this.id}`,
            value: t === "checkbox" ? [] : "",
            label: d.label,
            type: d.type,
            placeholder: d.placeholder,
            rules: newRules,
            message: d.message,
            groups: d.selectGroups,
            isShow: true,
            laravel_rule,
            config
          };

          // 根据状态处理表单：添加|编辑
          if (!this.isEdit) {
            f.push(formData);
            this.id = this.id + 1;
            this.resetForm("typeData");
            this.isShowAdd = false;
          } else {
            // 处理单选组件父子关联
            if (ef.type === "radio" && d.isChild) {
              ef.isChild = true;
              formData.parent_id = ef.name;
              formData.isShow = false;
              for (var idx2 in ef.groups) {
                if ("childList" in ef.groups[idx2] === false) {
                  ef.groups[idx2].childList = [];
                }
                for (var idx3 in d.ChildGroup) {
                  if (ef.groups[idx2].label === d.ChildGroup[idx3]) {
                    ef.groups[idx2].childList.push(formData.name);
                  }
                }
              }
            }
            for (var idx4 in f) {
              if (f[idx4].name === ef.name) {
                f.splice(Number(idx4) + 1, 0, formData);
                this.id = this.id + 1;
                this.resetForm("typeData");
                this.isShowAdd = false;
                this.isEdit = false;
                this.isEditData = null;
                break;
              }
            }
          }
        }
      });
    },
    // 增加选项时触发
    addOption() {
      this.typeData.selectGroups.push({
        label: "",
        value: ""
      });
    },
    // 删除选项时触发
    delOption(idx) {
      this.typeData.selectGroups.splice(idx, 1);
    },
    // 增加规则时触发
    addRules() {
      this.changeRuleSelect();
      this.typeData.rules.push({
        rule: "",
        value: ""
      });
    },
    // 删除规则时触发
    delRules(idx) {
      let rg = this.rulesGroups;
      let rule = this.typeData.rules[idx].rule;
      // 已选中规则禁用
      for (var i in rg) {
        if (rg[i].value === rule) {
          console.log(true);
          rg[i].isDisabled = false;
          // 若选中唯一规则，则启用剩余唯一规则
          if (rg[i].only === true) {
            for (var idx1 in rg[idx1]) {
              rg[idx1].isDisabled = false;
            }
          }
        }
      }
      this.typeData.rules.splice(idx, 1);
      if (this.typeData.rules.length === 1) {
        for (var idx2 in rg) {
          rg[idx2].isDisabled = false;
        }
      }
    },
    // 当规则变化时，改变规则选项显示
    changeRuleSelect() {
      let rg = this.rulesGroups;
      for (var idx1 in this.typeData.rules) {
        for (var idx2 in rg) {
          if (this.typeData.rules[idx1].rule === rg[idx2].value) {
            rg[idx2].isDisabled = true;
            // 若选中唯一规则，则禁用剩余唯一规则
            if (rg[idx2].only) {
              console.log(true);
              for (var idx3 in rg) {
                if (rg[idx3].only) {
                  rg[idx3].isDisabled = true;
                }
              }
            }
          }
        }
      }
    },
    // 提交表单数据
    onSumbit(res) {
      console.log(res);
    },
    // 编辑————删除组件
    delComponent(data) {
      let f = this.formData;
      this.$confirm("是否删除?").then(() => {
        for (var index in f) {
          if (f[index].name === data.name) {
            f.splice(index, 1);
            this.resetForm("typeData");
            break;
          }
        }
      });
    },
    // 显示编辑按钮
    editForm() {
      this.isShowEditIcon = !this.isShowEditIcon;
      this.$refs.drag.dragabled = !this.$refs.drag.dragabled;
    },
    // 确认保存表单
    saveForm() {
      console.log(this.formData);
      let select_map = "";
      for (var i in this.formData) {
        select_map += `${this.formData[i].name},`;
      }
      select_map = select_map.substr(0, select_map.length - 1);

      let data = {
        data:this.formData,
        form_name:'测试表单',
        user_id:1,
        select_map,
      }
      this.$req.put(this.$api.addForm,data).then(res => {
        console.log(res);
      })
    },
    formDrag(res) {
      console.log(res);
      this.formData = res;
    }
  }
};
</script>
<style lang='scss'>
.test4 {
  display: flex;
  flex-direction: column;
  align-items: center;
  .title {
    display: inline-block;
    margin-bottom: 50px;
  }
  .formBox {
    width: 100%;
    display: flex;
    margin-bottom: 20px;
  }
  // 弹窗
  .typeForm {
    .el-form-item {
      .el-form-item__content {
        display: flex;
      }
    }
    .el-input {
      width: 300px;
    }
    .option_box,
    .rules_box {
      display: flex;
      margin: 0;
      .el-form-item__content {
        margin-left: 0 !important;
      }
      .option_group,
      .rules_group {
        display: flex;
        flex-direction: column;
        .option_content,
        .rules_content {
          display: flex;
          margin-bottom: 20px;
          .rules {
            display: flex;
            flex-direction: column;
            .rules_input {
              margin-top: 20px;
            }
          }
          .icon_box {
            height: 40px;
            cursor: pointer;
            display: inline-block;
            margin-left: 10px;
            margin-top: 3px;
            font-size: 30px;
            &:hover {
              color: #409eff;
            }
          }
        }
      }
    }
    .radio_groups {
      display: flex;
      align-items: center;
      .el-form-item__content {
        margin-left: 10px !important;
      }
    }
    .button_group {
      margin-top: 20px;
    }
  }
  // 表单属性
  .form_template {
    display: flex;
    .icon_box {
      height: 40px;
      cursor: pointer;
      display: inline-block;
      margin-left: 10px;
      margin-top: 3px;
      font-size: 30px;
      &:hover {
        color: #409eff;
      }
    }
  }
}
</style>